#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
解码器标签页模块
实现从图片中恢复文件的功能
"""

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import threading
import os

from qr_decoder import QRDecoder


class ReceiverTab:
    def __init__(self, parent):
        self.parent = parent
        self.decoder = QRDecoder()
        self.logger = None
        self.progress_var = None
        self.progress_label = None
        self.create_widgets()

    def create_widgets(self):
        """创建解码器界面"""
        self.frame = ttk.Frame(self.parent)
        self.frame.pack(fill='both', expand=True)
        
        # 目录选择区域
        dir_frame = ttk.LabelFrame(self.frame, text="图片目录选择", padding="8")
        dir_frame.pack(fill='x', padx=8, pady=5)
        
        ttk.Label(dir_frame, text="选择包含二维码图片的目录:").grid(row=0, column=0, sticky='w', padx=5, pady=5)
        
        self.dir_path_var = tk.StringVar()
        self.dir_entry = ttk.Entry(dir_frame, textvariable=self.dir_path_var)
        self.dir_entry.grid(row=0, column=1, sticky='ew', padx=5, pady=5)
        
        ttk.Button(dir_frame, text="浏览", command=self.browse_directory).grid(row=0, column=2, padx=5, pady=5)

        # 配置列权重使文本框自适应宽度
        dir_frame.columnconfigure(1, weight=1)
        
        # 操作按钮区域
        button_frame = ttk.Frame(self.frame)
        button_frame.pack(fill='x', padx=8, pady=5)
        
        self.scan_btn = ttk.Button(button_frame, text="扫描并恢复", command=self.scan_directory)
        self.scan_btn.pack(side=tk.LEFT, padx=5)

    def set_logger(self, logger):
        """设置日志器"""
        self.logger = logger
        
    def set_progress(self, progress_var, progress_label):
        """设置进度条"""
        self.progress_var = progress_var
        self.progress_label = progress_label

    def _update_progress(self, progress):
        """更新进度条"""
        if self.progress_var:
            self.progress_var.set(progress)
        if self.progress_label:
            self.progress_label.config(text=f"正在处理... {progress:.1f}%")
        
    def browse_directory(self):
        """浏览选择目录"""
        directory = filedialog.askdirectory(title="选择包含二维码图片的目录")
        if directory:
            self.dir_path_var.set(directory)
            if self.logger:
                self.logger.info(f"已选择扫描目录: {directory}")

    def scan_directory(self):
        """扫描并自动恢复文件"""
        directory = self.dir_path_var.get()
        if not directory or not os.path.exists(directory):
            messagebox.showerror("错误", "请选择有效的目录")
            return
            
        # 禁用按钮
        self.scan_btn.config(state=tk.DISABLED)
        
        # 在新线程中扫描并自动恢复
        thread = threading.Thread(target=self._scan_and_recover_thread, args=(directory,))
        thread.daemon = True
        thread.start()

    def _scan_and_recover_thread(self, directory):
        """扫描并自动恢复文件的线程函数"""
        try:
            if self.logger:
                self.logger.info("开始扫描目录...")
                
            # 更新进度条
            if self.progress_var:
                self.progress_var.set(0)
            if self.progress_label:
                self.progress_label.config(text="正在扫描...")
                
            # 检查目录是否存在
            if not os.path.exists(directory):
                raise FileNotFoundError(f"目录不存在: {directory}")
                
            # 获取图片文件列表
            image_files = []
            for file in os.listdir(directory):
                if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif', '.tiff')):
                    image_files.append(os.path.join(directory, file))
                    
            if self.logger:
                self.logger.info(f"找到 {len(image_files)} 个图片文件")
                
            if not image_files:
                self.logger.warning("目录中没有找到图片文件")
                self.parent.after(0, lambda: messagebox.showwarning("警告", "目录中没有找到图片文件"))
                self.parent.after(0, lambda: self._on_scan_error("目录中没有找到图片文件"))
                return
            # 扫描二维码（一旦找到完整文件就提前结束）
            self.logger.info("开始扫描目录，寻找第一个可恢复的完整文件...")
            qr_data_map = self.decoder.scan_qr_codes(directory, progress_callback=self._update_progress, logger=self.logger)
            
            if not qr_data_map:
                self.logger.warning("未找到任何二维码数据")
                self.parent.after(0, lambda: self._on_scan_error("未找到任何二维码数据"))
                return
                
            # 由于scan_qr_codes已提前结束，qr_data_map只包含一个完整文件
            target_file = list(qr_data_map.keys())[0]
            file_qr_count = len(qr_data_map[target_file])
            
            self.logger.success(f"扫描完成，找到文件 '{target_file}' 的 {file_qr_count} 个二维码")
            
            # 开始恢复文件
            self.logger.info(f"开始恢复文件: {target_file}")
            if self.progress_var:
                self.progress_var.set(0)
            if self.progress_label:
                self.progress_label.config(text="正在恢复文件...")
                
            # 清空输出目录
            output_dir = "out"
            if os.path.exists(output_dir):
                for file in os.listdir(output_dir):
                    file_path = os.path.join(output_dir, file)
                    if os.path.isfile(file_path):
                        os.remove(file_path)
                        
            # 直接恢复找到的文件
            self.logger.info(f"输出目录: {output_dir}")
            recovered_files = self.decoder.reconstruct_file(qr_data_map, output_dir, logger=self.logger)
            
            if recovered_files:
                self.logger.success(f"文件恢复完成，成功恢复1个文件")
                file_path = recovered_files[0]
                file_size = os.path.getsize(file_path)
                self.logger.info(f"已恢复: {os.path.basename(file_path)} ({file_size} 字节)")
            else:
                self.logger.warning("没有成功恢复的文件")
                
            # 更新UI
            self.parent.after(0, lambda: self._on_recover_complete(recovered_files))

        except Exception as e:
            error_msg = str(e)
            if self.logger:
                self.logger.error(f"操作失败: {error_msg}")
            self.parent.after(0, lambda: self._on_scan_error(error_msg))

    def _on_scan_error(self, error_msg):
        """扫描失败的回调"""
        self.scan_btn.config(state=tk.NORMAL)
        messagebox.showerror("错误", f"扫描目录失败: {error_msg}")
        if self.progress_var:
            self.progress_var.set(0)
        if self.progress_label:
            self.progress_label.config(text="扫描失败")
            
    def _on_recover_complete(self, recovered_files):
        """恢复完成后的回调"""
        self.scan_btn.config(state=tk.NORMAL)
        
        if recovered_files:
            messagebox.showinfo("成功", f"成功恢复 {len(recovered_files)} 个文件到 out 目录")
        else:
            messagebox.showwarning("警告", "没有文件被恢复")
            
        if self.progress_var:
            self.progress_var.set(100)
        if self.progress_label:
            self.progress_label.config(text="恢复完成")
            
    def _on_recover_error(self, error_msg):
        """恢复失败的回调"""
        self.scan_btn.config(state=tk.NORMAL)
        messagebox.showerror("错误", f"恢复文件失败: {error_msg}")
        if self.progress_var:
            self.progress_var.set(0)
        if self.progress_label:
            self.progress_label.config(text="恢复失败")